import { acceptHMRUpdate, defineStore } from "pinia";
import { shallowRef } from "vue";
import type { IDENames, JetbrainsTool, JetbrainsToolboxState, LocalIdeItem } from "./types.ts";
import path from "@/framework/util/path.ts";
import { getFileIconBase64 } from "@/util/system-utils2.ts";

/**
 * 本机IDE软件管理
 */
export const useIdeStore = defineStore("ide", () => {
  /**
   * 本机已安装IDE列表
   */
  const localIdes = shallowRef<Partial<Record<IDENames, LocalIdeItem[]>>>({});

  const jbTool2LocalIde = (tool: JetbrainsTool, name: string): LocalIdeItem => ({
    key: tool.toolId,
    name: tool.displayName,
    icon: path.join(tool.installLocation, `bin/${name}.svg`),
    version: tool.displayVersion,
    launchCmd: tool.launchCommand,
  });

  const findVsCode = async (): Promise<LocalIdeItem[]> => {
    let vscodeBin = "C:\\Program Files\\Microsoft VS Code\\Code.exe";
    if (!(await native.fs.exists(vscodeBin))) {
      vscodeBin = path.join(native.process.env.LOCALAPPDATA, "Programs\\Microsoft VS Code\\Code.exe");
    }
    if (await native.fs.exists(vscodeBin)) {
      const icon = await getFileIconBase64(vscodeBin);
      return [
        {
          key: "vscode",
          name: "Visual Studio Code",
          version: "",
          icon,
          launchCmd: vscodeBin,
        },
      ];
    }
    return [];
  };

  const findVS = async (): Promise<LocalIdeItem[]> => {
    const baseDir = "C:\\Program Files\\Microsoft Visual Studio";
    const versions = await native.fs.readdir(baseDir);
    const items: LocalIdeItem[] = [];
    for (const versionDir of versions) {
      const editions = await native.fs.readdir(versionDir);
      for (const editionDir of editions) {
        const visualStudioBin = path.join(editionDir, "Common7\\IDE\\devenv.exe");
        if (await native.fs.exists(visualStudioBin)) {
          const version = path.basename(versionDir);
          const edition = path.basename(editionDir);
          const icon = await getFileIconBase64(visualStudioBin);
          items.push({
            key: `vs-${edition}-${version}`,
            name: `Visual Studio ${edition} ${version}`,
            icon,
            version,
            launchCmd: visualStudioBin,
          });
        }
      }
    }

    return items;
  };

  const loadLocalIde = async () => {
    const jbStateJsonFile = path.join(native.process.env.LOCALAPPDATA, "JetBrains\\Toolbox\\state.json");
    const jbToolboxState = await native.fs.readFileJson<JetbrainsToolboxState>(jbStateJsonFile);

    const ides: Partial<Record<IDENames, LocalIdeItem[]>> = {};

    if (jbToolboxState) {
      ides.idea = jbToolboxState.tools.filter(it => it.toolId.toLowerCase().startsWith("idea")).map(it => jbTool2LocalIde(it, "idea"));
      ides.webstorm = jbToolboxState.tools.filter(it => it.toolId.toLowerCase() == "webstorm").map(it => jbTool2LocalIde(it, "webstorm"));
      ides.pycharm = jbToolboxState.tools.filter(it => it.toolId.toLowerCase().startsWith("pycharm")).map(it => jbTool2LocalIde(it, "pycharm"));
      ides.rider = jbToolboxState.tools.filter(it => it.toolId.toLowerCase() === "rider").map(it => jbTool2LocalIde(it, "rider"));
      ides.clion = jbToolboxState.tools.filter(it => it.toolId.toLowerCase() === "clion").map(it => jbTool2LocalIde(it, "clion"));
      ides.rustover = jbToolboxState.tools.filter(it => it.toolId.toLowerCase() === "rustover").map(it => jbTool2LocalIde(it, "rustover"));
      ides.phpstorm = jbToolboxState.tools.filter(it => it.toolId.toLowerCase() === "phpstorm").map(it => jbTool2LocalIde(it, "phpstorm"));
      ides.goland = jbToolboxState.tools.filter(it => it.toolId.toLowerCase() === "goland").map(it => jbTool2LocalIde(it, "goland"));
      ides.androidStudio = jbToolboxState.tools.filter(it => it.toolId.toLowerCase() === "androidstudio").map(it => jbTool2LocalIde(it, "studio"));
    }

    ides.vscode = await findVsCode();
    ides.vs = await findVS();

    localIdes.value = ides;
  };

  return {
    locals: localIdes,
    loadLocalIde: loadLocalIde,
  };
});

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useIdeStore, import.meta.hot));
}
